package com.cloudbroker.bcs.platform.ltb.common.payUtil;

import com.alibaba.fastjson.JSONArray;
import com.sun.org.apache.xml.internal.security.utils.Base64;
import org.apache.log4j.Logger;

import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.util.Map;
import java.util.TreeMap;

/**
 * @ClassName EncryptUtil
 * @Description 加签以及验证签名
 * @author yangchun@hundsun.com
 * 
 *         <pre>
 *         说明： 以下代码只是为了方便商户测试而提供的样例代码，商户可以根据自己网站的需要，按照技术文档编写,并非一定要使用该代码。
 *         该代码仅供学习和研究三峡付接口使用，只是提供一个
 * @date 2014年10月16日
 */
public class EncryptUtil {
	/**
	 * 签名算法
	 */
	public static final String SIGNATURE_ALGORITHM = "SHA1withRSA";
	public static Logger loggger = Logger.getLogger (EncryptUtil.class);

	/**
	 * @Method: sort
	 * @Description: TODO(这里用一句话描述这个方法的作用)
	 * @param @param map
	 * @param @return
	 * @return StringBuilder
	 * @throws
	 */
	public static String sortSource(Map<String, Object> map) {

		if (null == map) {
			return "";
		}
		String sorted = sortMap (map);

		if (null != sorted && !"".equals (sorted) && '&' == sorted.charAt (0)) {
			sorted = sorted.substring (1, sorted.length ());
		}
		return sorted;
	}

	@SuppressWarnings("unchecked")
    private static String sortMap(Map<String, Object> map) {
		StringBuilder msg = new StringBuilder ();
		if (map.containsKey ("cert_sign")) {
			map.remove ("cert_sign");
		}
		TreeMap<String, Object> treeMap = new TreeMap<String, Object> (new CustomTreeMapComparator<String> ());
		treeMap.putAll (map);
		Object[] keys = treeMap.keySet ().toArray ();
		if (null != keys && keys.length > 0) {
			for (int i = 0; i < keys.length; i++) {
				if (null != treeMap.get (keys[i])) {
					Object value = treeMap.get (keys[i]);
					if (value instanceof JSONArray) {
						JSONArray jsonArray = (JSONArray) value;
						for (Object jsonObj : jsonArray) {
							msg.append (sortMap ((Map<String, Object>) jsonObj));
						}
					} else
						if (null != value && !"".equals (value.toString ())) {
							msg.append ("&").append (keys[i]).append ("=").append (value.toString ());
						}
				}
			}
		}
		return msg.toString ();
	}

	/**
	 * @throws Exception
	 * 
	 * @Method: doSign
	 * @Description: 加签
	 * @param @param data 原文
	 * @param @param privateKey 私钥
	 * @param @return 签名串
	 * @param @param charSet 原文字符集
	 * @return String
	 * @throws
	 */
	public static String doSign(String ori, PrivateKey privateKey, String charSet) throws Exception {
		Signature signature = Signature.getInstance (SIGNATURE_ALGORITHM);
		signature.initSign (privateKey);
		signature.update (ori.getBytes (charSet));
		return Base64.encode (signature.sign ());
	}

	/**
	 * @Method: verify
	 * @Description: 验证签名
	 * @param @param ori 原文
	 * @param @param publicKey 公钥
	 * @param @param sign 签名串
	 * @param @param charSet 原文字符集
	 * @param @throws Exception
	 * @return boolean
	 * @throws
	 */
	public static boolean verify(String ori, PublicKey publicKey, String sign, String charSet) throws Exception {
		Signature signature = Signature.getInstance (SIGNATURE_ALGORITHM);
		signature.initVerify (publicKey);
		signature.update (ori.getBytes (charSet));
		return signature.verify (Base64.decode (sign));
	}
}
